{
  "nbformat_minor": 0,
  "nbformat": 4,
  "cells": [
    {
      "source": [
        "#### Copyright 2017 Google LLC."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "JndnmDMp66FL"
      }
    },
    {
      "source": [
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "hMqWDc_m6rUC",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        },
        "cellView": "both"
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " # Cr\u00e9er et manipuler des Tensors"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "P0bQXjp499sl"
      }
    },
    {
      "source": [
        " **Objectifs de formation**\u00a0:\n",
        "  * Initialiser et affecter des objets `Variable` TensorFlow\n",
        "  * Cr\u00e9er et manipuler des Tensors\n",
        "  * Rafra\u00eechir ses connaissances sur les op\u00e9rations de somme et de produit en alg\u00e8bre lin\u00e9aire (lecture conseill\u00e9e de l'introduction \u00e0 l'[addition](https://fr.wikipedia.org/wiki/Addition_matricielle) et au [produit](https://fr.wikipedia.org/wiki/Produit_matriciel) matriciels, si ces notions vous sont inconnues)\n",
        "  * Se familiariser avec les op\u00e9rations math\u00e9matiques et de tableau basiques dans TensorFlow"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "I3BCiWJiCGsv"
      }
    },
    {
      "source": [
        "from __future__ import print_function\n\n",
        "import tensorflow as tf"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "85evKRsOIC5a",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## Somme vectorielle\n",
        "\n",
        "Vous pouvez r\u00e9aliser de nombreuses op\u00e9rations math\u00e9matiques standards sur les Tensors (reportez-vous \u00e0 l'[API TensorFlow](https://www.tensorflow.org/api_guides/python/math_ops)). Le code suivant permet de cr\u00e9er et de manipuler deux\u00a0vecteurs (Tensors \u00e0 une\u00a0dimension), constitu\u00e9s chacun de six\u00a0\u00e9l\u00e9ments\u00a0:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "PT1sorfH-DdQ"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create a six-element vector (1-D tensor).\n",
        "  primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)\n",
        "\n",
        "  # Create another six-element vector. Each element in the vector will be\n",
        "  # initialized to 1. The first argument is the shape of the tensor (more\n",
        "  # on shapes below).\n",
        "  ones = tf.ones([6], dtype=tf.int32)\n",
        "\n",
        "  # Add the two vectors. The resulting tensor is a six-element vector.\n",
        "  just_beyond_primes = tf.add(primes, ones)\n",
        "\n",
        "  # Create a session to run the default graph.\n",
        "  with tf.Session() as sess:\n",
        "    print(just_beyond_primes.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "ng37e6ur-GZo",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Formats de Tensor\n",
        "\n",
        "Le format caract\u00e9rise la taille et le nombre de dimensions d'un Tensor. Il est indiqu\u00e9 sous la forme d'une liste, o\u00f9 le `i`e\u00a0\u00e9l\u00e9ment d\u00e9signe la taille par rapport \u00e0 la dimension `i`. La longueur de la liste indique le rang du Tensor (c'est-\u00e0-dire le nombre de dimensions).\n",
        "\n",
        "Pour en savoir plus, consultez la [documentation TensorFlow](https://www.tensorflow.org/programmers_guide/tensors#shape).\n",
        "\n",
        "Quelques exemples basiques\u00a0:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "fVvaXzzMGZid"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # A scalar (0-D tensor).\n",
        "  scalar = tf.zeros([])\n",
        "\n",
        "  # A vector with 3 elements.\n",
        "  vector = tf.zeros([3])\n",
        "\n",
        "  # A matrix with 2 rows and 3 columns.\n",
        "  matrix = tf.zeros([2, 3])\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print('scalar has shape', scalar.get_shape(), 'and value:\\n', scalar.eval())\n",
        "    print('vector has shape', vector.get_shape(), 'and value:\\n', vector.eval())\n",
        "    print('matrix has shape', matrix.get_shape(), 'and value:\\n', matrix.eval())\n"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "PWzvJnIAH_cF",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Broadcasting\n",
        "\n",
        "En math\u00e9matiques, les Tensors de format identique peuvent subir uniquement des op\u00e9rations au niveau de l'\u00e9l\u00e9ment (op\u00e9rations *ajouter* et *\u00e9gal*, par exemple). Dans TensorFlow, en revanche, il est possible de r\u00e9aliser des op\u00e9rations traditionnellement incompatibles. ce mod\u00e8le autorise ainsi le **broadcasting** (un concept emprunt\u00e9 \u00e0 Numpy), qui permet d'agrandir un petit tableau pour qu'il prenne le m\u00eame format que le grand tableau. Exemples de possibilit\u00e9s offertes par le broadcasting\u00a0:\n",
        "\n",
        "* Si une op\u00e9ration exige un Tensor de taille `[6]`, un Tensor de taille `[1]` ou `[]` peut \u00eatre utilis\u00e9 comme op\u00e9rande.\n",
        "* Si une op\u00e9ration exige un Tensor de taille `[4, 6]`, vous pouvez utiliser comme op\u00e9rande l'une des tailles de Tensor suivantes\u00a0:\n",
        "  * `[1, 6]`\n",
        "  * `[6]`\n",
        "  * `[]`\n",
        "* Si une op\u00e9ration exige un Tensor de taille `[3, 5, 6]`, vous pouvez utiliser comme op\u00e9rande l'une des tailles de Tensor suivantes\u00a0:\n",
        "\n",
        "  * `[1, 5, 6]`\n",
        "  * `[3, 1, 6]`\n",
        "  * `[3, 5, 1]`\n",
        "  * `[1, 1, 1]`\n",
        "  * `[5, 6]`\n",
        "  * `[1, 6]`\n",
        "  * `[6]`\n",
        "  * `[1]`\n",
        "  * `[]`\n",
        "  \n",
        "**REMARQUE**\u00a0: Lorsqu'un Tensor est broadcast\u00e9, ses entr\u00e9es sont **copi\u00e9es** de mani\u00e8re conceptuelle. (Elles ne sont pas r\u00e9ellement copi\u00e9es, pour des raisons li\u00e9es aux performances. Le broadcasting a \u00e9t\u00e9 con\u00e7u comme un outil d'optimisation des performances.)\n",
        "\n",
        "La [documentation sur le broadcasting Numpy](http://docs.scipy.org/doc/numpy-1.10.1/user/basics.broadcasting.html), qui se veut facile d'acc\u00e8s, fournit une description d\u00e9taill\u00e9e de l'ensemble de r\u00e8gles de broadcasting.\n",
        "\n",
        "Le code suivant reprend l'op\u00e9ration de somme de Tensors pr\u00e9c\u00e9dente, cette fois avec le broadcasting\u00a0:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "musamrLavR5S"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create a six-element vector (1-D tensor).\n",
        "  primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)\n",
        "\n",
        "  # Create a constant scalar with value 1.\n",
        "  ones = tf.constant(1, dtype=tf.int32)\n",
        "\n",
        "  # Add the two tensors. The resulting tensor is a six-element vector.\n",
        "  just_beyond_primes = tf.add(primes, ones)\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print(just_beyond_primes.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "7lys_BeLy2SD",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## Produit matriciel\n",
        "\n",
        "En alg\u00e8bre lin\u00e9aire, lorsque vous calculez le produit de deux\u00a0matrices, le nombre de *colonnes* dans la premi\u00e8re doit \u00eatre \u00e9gal au nombre de *lignes* dans la seconde.\n",
        "\n",
        "- Une matrice `3x4` **peut** \u00eatre multipli\u00e9e par une matrice `4x2`. Vous obtiendrez une matrice `3x2`.\n",
        "- Une matrice `4x2` **ne peut pas** \u00eatre multipli\u00e9e par une matrice `3x4`."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "it0P-AV0-Jb4"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create a matrix (2-d tensor) with 3 rows and 4 columns.\n",
        "  x = tf.constant([[5, 2, 4, 3], [5, 1, 6, -2], [-1, 3, -1, -2]],\n",
        "                  dtype=tf.int32)\n",
        "\n",
        "  # Create a matrix with 4 rows and 2 columns.\n",
        "  y = tf.constant([[2, 2], [3, 5], [4, 5], [1, 6]], dtype=tf.int32)\n",
        "\n",
        "  # Multiply `x` by `y`. \n",
        "  # The resulting matrix will have 3 rows and 2 columns.\n",
        "  matrix_multiply_result = tf.matmul(x, y)\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print(matrix_multiply_result.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "OVR8QPif-MeS",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## Modification du format des Tensors\n",
        "\n",
        "La somme de Tensors et le produit matriciel sont deux\u00a0op\u00e9rations qui imposent des contraintes sp\u00e9cifiques aux op\u00e9randes, obligeant ainsi les programmeurs TensorFlow \u00e0 modifier r\u00e9guli\u00e8rement le format des Tensors. \n",
        "\n",
        "La m\u00e9thode `tf.reshape` permet de modifier le format d'un Tensor. \n",
        "Ainsi, un Tensor 8x2 peut \u00eatre converti en Tensor 2x8 ou 4x4\u00a0:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "fziRnmuy-O9x"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create an 8x2 matrix (2-D tensor).\n",
        "  matrix = tf.constant([[1,2], [3,4], [5,6], [7,8],\n",
        "                        [9,10], [11,12], [13, 14], [15,16]], dtype=tf.int32)\n",
        "\n",
        "  # Reshape the 8x2 matrix into a 2x8 matrix.\n",
        "  reshaped_2x8_matrix = tf.reshape(matrix, [2,8])\n",
        "  \n",
        "  # Reshape the 8x2 matrix into a 4x4 matrix\n",
        "  reshaped_4x4_matrix = tf.reshape(matrix, [4,4])\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print(\"Original matrix (8x2):\")\n",
        "    print(matrix.eval())\n",
        "    print(\"Reshaped matrix (2x8):\")\n",
        "    print(reshaped_2x8_matrix.eval())\n",
        "    print(\"Reshaped matrix (4x4):\")\n",
        "    print(reshaped_4x4_matrix.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "L05ob6a_G77m",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " \n",
        "Vous pouvez \u00e9galement utiliser `tf.reshape` pour modifier le nombre de dimensions (le \\'rang\\') d'un Tensor.\n",
        "Par exemple, le m\u00eame Tensor 8x2 peut \u00eatre converti en Tensor 2x2x4 \u00e0 trois\u00a0dimensions ou en Tensor une\u00a0dimension de 16\u00a0\u00e9l\u00e9ments."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "b6cFa92YGyU5"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default():\n",
        "  # Create an 8x2 matrix (2-D tensor).\n",
        "  matrix = tf.constant([[1,2], [3,4], [5,6], [7,8],\n",
        "                        [9,10], [11,12], [13, 14], [15,16]], dtype=tf.int32)\n",
        "\n",
        "  # Reshape the 8x2 matrix into a 3-D 2x2x4 tensor.\n",
        "  reshaped_2x2x4_tensor = tf.reshape(matrix, [2,2,4])\n",
        "  \n",
        "  # Reshape the 8x2 matrix into a 1-D 16-element tensor.\n",
        "  one_dimensional_vector = tf.reshape(matrix, [16])\n",
        "\n",
        "  with tf.Session() as sess:\n",
        "    print(\"Original matrix (8x2):\")\n",
        "    print(matrix.eval())\n",
        "    print(\"Reshaped 3-D tensor (2x2x4):\")\n",
        "    print(reshaped_2x2x4_tensor.eval())\n",
        "    print(\"1-D vector:\")\n",
        "    print(one_dimensional_vector.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "3MpcwWj9-Sqp",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Exercice n\u00b0\u00a01\u00a0: Modifier le format de deux\u00a0Tensors pour les multiplier\n",
        "\n",
        "L'op\u00e9ration de produit matriciel est impossible sur les deux\u00a0vecteurs suivants\u00a0:\n",
        "\n",
        "  *  `a = tf.constant([5, 3, 2, 7, 1, 4])`\n",
        "  *  `b = tf.constant([4, 6, 3])`\n",
        "\n",
        "Modifiez leur format pour les convertir en op\u00e9randes compatibles avec l'op\u00e9ration de produit matriciel.\n",
        "R\u00e9alisez ensuite cette op\u00e9ration sur les Tensors ainsi modifi\u00e9s."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "CrpowaWo-VLq"
      }
    },
    {
      "source": [
        "  # Write your code for Task 1 here."
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "p6idvaeK-Zxq",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Solution\n",
        "\n",
        "Cliquez ci-dessous pour afficher la solution."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "EYzU56M4MG_x"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default(), tf.Session() as sess:\n",
        "  # Task: Reshape two tensors in order to multiply them\n",
        "  \n",
        "  # Here are the original operands, which are incompatible\n",
        "  # for matrix multiplication:\n",
        "  a = tf.constant([5, 3, 2, 7, 1, 4])\n",
        "  b = tf.constant([4, 6, 3])\n",
        "  # We need to reshape at least one of these operands so that\n",
        "  # the number of columns in the first operand equals the number\n",
        "  # of rows in the second operand.\n",
        "\n",
        "  # Reshape vector \"a\" into a 2-D 2x3 matrix:\n",
        "  reshaped_a = tf.reshape(a, [2,3])\n",
        "\n",
        "  # Reshape vector \"b\" into a 2-D 3x1 matrix:\n",
        "  reshaped_b = tf.reshape(b, [3,1])\n",
        "\n",
        "  # The number of columns in the first matrix now equals\n",
        "  # the number of rows in the second matrix. Therefore, you\n",
        "  # can matrix mutiply the two operands.\n",
        "  c = tf.matmul(reshaped_a, reshaped_b)\n",
        "  print(c.eval())\n",
        "\n",
        "  # An alternate approach: [6,1] x [1, 3] -> [6,3]"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "8Sef4d0SMMtk",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## Variables, initialisation et affectation\n",
        "\n",
        "Les op\u00e9rations r\u00e9alis\u00e9es jusqu'\u00e0 maintenant portaient uniquement sur des valeurs statiques (`tf.constant`). L'appel de la m\u00e9thode `eval()` renvoyait syst\u00e9matiquement le m\u00eame r\u00e9sultat. Avec TensorFlow, vous pouvez d\u00e9finir des objets `Variable`, dont la valeur peut changer. \n",
        "\n",
        "Lors de la cr\u00e9ation d'une variable, vous avez le choix entre d\u00e9finir explicitement sa valeur initiale ou utiliser un initialiseur (comme pour une distribution)\u00a0:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "x1JYo7iE2oKk"
      }
    },
    {
      "source": [
        "g = tf.Graph()\n",
        "with g.as_default():\n",
        "  # Create a variable with the initial value 3.\n",
        "  v = tf.Variable([3])\n",
        "\n",
        "  # Create a variable of shape [1], with a random initial value,\n",
        "  # sampled from a normal distribution with mean 1 and standard deviation 0.35.\n",
        "  w = tf.Variable(tf.random_normal([1], mean=1.0, stddev=0.35))"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "6opLnjfD3PdL",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " L'une des particularit\u00e9s de TensorFlow est que l'**initialisation des variables n'est pas automatique**. Ainsi, le bloc suivant renverra une erreur\u00a0:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "qDYRXHTA4PTB"
      }
    },
    {
      "source": [
        "with g.as_default():\n",
        "  with tf.Session() as sess:\n",
        "    try:\n",
        "      v.eval()\n",
        "    except tf.errors.FailedPreconditionError as e:\n",
        "      print(\"Caught expected error: \", e)"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "d0OX1YRY5PTP",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " Le plus simple pour initialiser une variable consiste \u00e0 appeler `global_variables_initializer`. La m\u00e9thode `Session.run()` employ\u00e9e ici \u00e9quivaut \u00e0 `eval()`, \u00e0 peu de chose pr\u00e8s."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "v7_aT7Hr5rnC"
      }
    },
    {
      "source": [
        "with g.as_default():\n",
        "  with tf.Session() as sess:\n",
        "    initialization = tf.global_variables_initializer()\n",
        "    sess.run(initialization)\n",
        "    # Now, variables can be accessed normally, and have values assigned to them.\n",
        "    print(v.eval())\n",
        "    print(w.eval())\n"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "z2lvhrxI5zJF",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " Une fois initialis\u00e9es, les variables conservent leur valeur pour toute la session (il convient de les r\u00e9initialiser au d\u00e9marrage d'une nouvelle session)\u00a0:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "0GkYh7jf6JUd"
      }
    },
    {
      "source": [
        "with g.as_default():\n",
        "  with tf.Session() as sess:\n",
        "    sess.run(tf.global_variables_initializer())\n",
        "    # These three prints will print the same value.\n",
        "    print(w.eval())\n",
        "    print(w.eval())\n",
        "    print(w.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "_E8_lhS06IoV",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " Pour modifier la valeur d'une variable, utilisez l'op\u00e9ration `assign`. Cr\u00e9er simplement cette op\u00e9ration n'a aucun effet. Comme pour l'initialisation, vous devez ex\u00e9cuter l'op\u00e9ration d'affectation (via `run`) pour pouvoir mettre \u00e0 jour la valeur de la variable\u00a0:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "yrZ31hPw66uy"
      }
    },
    {
      "source": [
        "with g.as_default():\n",
        "  with tf.Session() as sess:\n",
        "    sess.run(tf.global_variables_initializer())\n",
        "    # This should print the variable's initial value.\n",
        "    print(v.eval())\n",
        "\n",
        "    assignment = tf.assign(v, [7])\n",
        "    # The variable has not been changed yet!\n",
        "    print(v.eval())\n",
        "\n",
        "    # Execute the assignment op.\n",
        "    sess.run(assignment)\n",
        "    # Now the variable is updated.\n",
        "    print(v.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "zD0D1DCR7NBX",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " Chargement, stockage\u2026 les th\u00e9matiques autour des variables ne manquent pas. Pour en savoir plus sur un sujet non abord\u00e9 dans cette formation, consultez la [documentation TensorFlow](https://www.tensorflow.org/programmers_guide/variables)."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "tB78Zq4h78Zr"
      }
    },
    {
      "source": [
        " ### Exercice n\u00b0\u00a02\u00a0: Simuler 10\u00a0lancers de deux\u00a0d\u00e9s\n",
        "\n",
        "Simulez un lancer de d\u00e9s, qui g\u00e9n\u00e8re un Tensor `10x3` \u00e0 deux\u00a0dimensions\u00a0:\n",
        "\n",
        "  * Les colonnes `1` et `2` enregistrent un lancer de chaque d\u00e9.\n",
        "  * La colonne `3` contient la somme des colonnes `1` et `2`, sur la m\u00eame ligne.\n",
        "\n",
        "Exemple de valeurs sur la premi\u00e8re ligne\u00a0:\n",
        "\n",
        "  * Colonne `1`\u00a0: `4`\n",
        "  * Colonne `2`\u00a0: `3`\n",
        "  * Colonne `3`\u00a0: `7`\n",
        "\n",
        "Pour effectuer cet exercice, nous vous invitons \u00e0 consulter la [documentation TensorFlow](https://www.tensorflow.org/api_guides/python/array_ops)."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "iFIOcnfz_Oqw"
      }
    },
    {
      "source": [
        "# Write your code for Task 2 here."
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "ocwT0iXH-nhT",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ### Solution\n",
        "\n",
        "Cliquez ci-dessous pour afficher la solution."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "Kt7aojXkR_qS"
      }
    },
    {
      "source": [
        "with tf.Graph().as_default(), tf.Session() as sess:\n",
        "  # Task 2: Simulate 10 throws of two dice. Store the results\n",
        "  # in a 10x3 matrix.\n",
        "\n",
        "  # We're going to place dice throws inside two separate\n",
        "  # 10x1 matrices. We could have placed dice throws inside\n",
        "  # a single 10x2 matrix, but adding different columns of\n",
        "  # the same matrix is tricky. We also could have placed\n",
        "  # dice throws inside two 1-D tensors (vectors); doing so\n",
        "  # would require transposing the result.\n",
        "  dice1 = tf.Variable(tf.random_uniform([10, 1],\n",
        "                                        minval=1, maxval=7,\n",
        "                                        dtype=tf.int32))\n",
        "  dice2 = tf.Variable(tf.random_uniform([10, 1],\n",
        "                                        minval=1, maxval=7,\n",
        "                                        dtype=tf.int32))\n",
        "\n",
        "  # We may add dice1 and dice2 since they share the same shape\n",
        "  # and size.\n",
        "  dice_sum = tf.add(dice1, dice2)\n",
        "\n",
        "  # We've got three separate 10x1 matrices. To produce a single\n",
        "  # 10x3 matrix, we'll concatenate them along dimension 1.\n",
        "  resulting_matrix = tf.concat(\n",
        "      values=[dice1, dice2, dice_sum], axis=1)\n",
        "\n",
        "  # The variables haven't been initialized within the graph yet,\n",
        "  # so let's remedy that.\n",
        "  sess.run(tf.global_variables_initializer())\n",
        "\n",
        "  print(resulting_matrix.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "6UUluecQSCvr",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    }
  ],
  "metadata": {
    "colab": {
      "default_view": {},
      "version": "0.3.2",
      "collapsed_sections": [
        "JndnmDMp66FL",
        "EYzU56M4MG_x",
        "Kt7aojXkR_qS"
      ],
      "name": "creating_and_manipulating_tensors.ipynb",
      "views": {}
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  }
}
